package com.remoter.basic.configure.support;

import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.remoter.basic.configure.IConfiguration;
import com.remoter.basic.configure.Option;
import com.remoter.basic.util.Final;
import com.remoter.basic.util.ServiceLoader;
import com.remoter.basic.util.StringUtil;

/**
 * @author			koko
 * @date 			2017-08-08 14:39:55
 * @description 	类功能说明
 */
public abstract class AbstractConfiguration implements IConfiguration{
	
	protected static final Logger logger = LoggerFactory.getLogger(AbstractConfiguration.class);
	protected static final ConcurrentHashMap<String,Option<?>> options = new ConcurrentHashMap<String,Option<?>>();
	
	protected String getConfigFile(){
		String name = System.getProperty(Final.D_KEY_CONFIGURATION_NAME,Final.D_VAL_CONFIGURATION_NAME);
		String path = System.getProperty(Final.D_KEY_CONFIGURATION_PATH,Final.D_VAL_CONFIGURATION_PATH);
		return String.format("/%s.%s",name,path);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getOption(Option<T> option){
		if(null == option){
			return null;
		}
		String name = option.getName();
		Option<T> temp = (Option<T>)options.get(name);
		if(null == temp){
			options.put(name,option);
			temp = (Option<T>)options.get(name);
			String value = this.getValue(name);
			if(StringUtil.isNotBlank(value)){
				if(option.getValue() != null){
					if(option.getValue().getClass().equals(Integer.class)){
						temp.setValue((T)option.getValue().getClass().cast(Integer.parseInt(value)));
					}else if(option.getValue().getClass().equals(Double.class)){
						temp.setValue((T)option.getValue().getClass().cast(Double.parseDouble(value)));
					}else if(option.getValue().getClass().equals(Float.class)){
						temp.setValue((T)option.getValue().getClass().cast(Float.parseFloat(value)));
					}else if(option.getValue().getClass().equals(Boolean.class)){
						temp.setValue((T)option.getValue().getClass().cast(Boolean.parseBoolean(value)));
					}else if(option.getValue().getClass().equals(Long.class)){
						temp.setValue((T)option.getValue().getClass().cast(Long.parseLong(value)));
					}else if(option.getValue().getClass().equals(Short.class)){
						temp.setValue((T)option.getValue().getClass().cast(Short.parseShort(value)));
					}else if(option.getValue().getClass().equals(Byte.class)){
						temp.setValue((T)option.getValue().getClass().cast(Byte.parseByte(value)));
					}else if(option.getValue().getClass().equals(String.class)){
						temp.setValue((T)option.getValue().getClass().cast(String.valueOf(value)));
					}
				}else{
					temp.setValue((T)value);
				}
			}
		}
		return temp.getValue();
	}
	
	protected abstract String getValue(String name);
	
	public static IConfiguration getConfiguration(){
		String path = System.getProperty(Final.D_KEY_CONFIGURATION_PATH,Final.D_VAL_CONFIGURATION_PATH);
		IConfiguration configuration = ServiceLoader.getService(IConfiguration.class,path);
		if(null == configuration){
			throw new IllegalStateException("IConfiguration not found : " + path);
		}
		return configuration;
	}

}